package webhooks

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
	"webhook-agents/agents"
	"webhook-agents/config"
	"webhook-agents/core"
)

// KubeeventerEvent kubeeventer事件格式（数组）
type KubeeventerEvent struct {
	Events []agents.KubeEventAlert `json:"events"`
}

// KubeeventerFlatEvent kubeeventer扁平事件格式
type KubeeventerFlatEvent struct {
	EventType      string `json:"EventType"`
	EventKind      string `json:"EventKind"`
	EventReason    string `json:"EventReason"`
	EventTime      string `json:"EventTime"`
	EventMessage   string `json:"EventMessage"`
	EventObject    string `json:"EventObject"`
	EventNamespace string `json:"EventNamespace"`
}

// WebhookHandler webhook处理器
type WebhookHandler struct {
	agents map[string]*core.Agent
}

// NewWebhookHandler 创建新的webhook处理器
func NewWebhookHandler() *WebhookHandler {
	handler := &WebhookHandler{
		agents: make(map[string]*core.Agent),
	}

	// 注册SkyWalking agent
	skywalkingProcessor := agents.NewSkyWalkingProcessor()
	skywalkingAgent := core.NewAgent(
		"SkyWalking",
		"处理SkyWalking告警",
		skywalkingProcessor,
	)
	handler.agents["skywalking"] = skywalkingAgent

	// 注册Kubernetes事件 agent
	kubeEventProcessor := agents.NewKubeEventProcessor()
	kubeEventAgent := core.NewAgent(
		"KubeEvent",
		"处理Kubernetes事件",
		kubeEventProcessor,
	)
	handler.agents["kube-event"] = kubeEventAgent

	// 注册Falco agent
	falcoProcessor := agents.NewFalcoProcessor()
	falcoAgent := core.NewAgent(
		"Falco",
		"处理Falco告警",
		falcoProcessor,
	)
	handler.agents["falco"] = falcoAgent

	return handler
}

// HandleSkyWalkingAlert 处理SkyWalking告警（透传模式）
func (h *WebhookHandler) HandleSkyWalkingAlert(w http.ResponseWriter, r *http.Request) {
	// 检查端点是否启用
	if endpoint, ok := config.Global.Diting.Endpoints["skywalking"]; ok && !endpoint.Enabled {
		http.Error(w, "SkyWalking端点已禁用", http.StatusForbidden)
		return
	}

	// 支持GET和POST方法，但GET方法只返回确认信息
	if r.Method != http.MethodPost && r.Method != http.MethodGet {
		http.Error(w, "只支持GET和POST方法", http.StatusMethodNotAllowed)
		return
	}

	// 如果是GET请求，返回确认信息
	if r.Method == http.MethodGet {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		response := map[string]interface{}{
			"status":  "success",
			"message": "SkyWalking webhook endpoint is ready",
			"method":  r.Method,
			"source":  "skywalking",
		}
		json.NewEncoder(w).Encode(response)
		return
	}

	// 读取并打印原始请求体内容
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, fmt.Sprintf("读取请求体失败: %v", err), http.StatusBadRequest)
		return
	}

	// 打印接收到的原始数据
	fmt.Printf("📥 接收到的原始SkyWalking告警数据:\n%s\n", string(body))

	// 解析JSON数据以便传递给处理器
	var rawData interface{}
	if err := json.Unmarshal(body, &rawData); err != nil {
		http.Error(w, fmt.Sprintf("解析告警数据失败: %v", err), http.StatusBadRequest)
		return
	}

	// 记录接收到告警的时间
	receivedTime := time.Now()
	fmt.Printf("[%s] 🔔 接收到SkyWalking告警\n", receivedTime.Format("2006-01-02 15:04:05"))

	// 处理告警（透传模式）
	agent, ok := h.agents["skywalking"]
	if !ok {
		http.Error(w, "SkyWalking agent未注册", http.StatusInternalServerError)
		return
	}

	if err := agent.Process(rawData); err != nil {
		http.Error(w, fmt.Sprintf("处理告警失败: %v", err), http.StatusInternalServerError)
		return
	}

	// 计算处理时间
	processingTime := time.Since(receivedTime)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	response := map[string]interface{}{
		"status":          "success",
		"message":         "SkyWalking告警处理成功",
		"source":          "skywalking",
		"processing_time": fmt.Sprintf("%v", processingTime),
	}
	json.NewEncoder(w).Encode(response)
}

// HandleKubeEventAlert 处理Kubernetes事件
func (h *WebhookHandler) HandleKubeEventAlert(w http.ResponseWriter, r *http.Request) {
	// 检查端点是否启用
	if endpoint, ok := config.Global.Diting.Endpoints["kube_event"]; ok && !endpoint.Enabled {
		http.Error(w, "Kubernetes事件端点已禁用", http.StatusForbidden)
		return
	}

	// 支持GET和POST方法，但GET方法只返回确认信息
	if r.Method != http.MethodPost && r.Method != http.MethodGet {
		http.Error(w, "只支持GET和POST方法", http.StatusMethodNotAllowed)
		return
	}

	// 如果是GET请求，返回确认信息
	if r.Method == http.MethodGet {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		response := map[string]interface{}{
			"status":  "success",
			"message": "Kubernetes事件 webhook endpoint is ready",
			"method":  r.Method,
			"source":  "kube-event",
		}
		json.NewEncoder(w).Encode(response)
		return
	}

	// 读取并打印原始请求体内容
	body, err := io.ReadAll(r.Body)
	if err != nil {
		http.Error(w, fmt.Sprintf("读取请求体失败: %v", err), http.StatusBadRequest)
		return
	}

	// 打印接收到的原始数据
	fmt.Printf("📥 接收到的原始Kubernetes事件数据:\n%s\n", string(body))

	// 重新设置请求体，以便后续解析
	r.Body = io.NopCloser(bytes.NewBuffer(body))

	// 尝试解析kubeeventer扁平格式
	var flatEvent KubeeventerFlatEvent
	if err := json.NewDecoder(r.Body).Decode(&flatEvent); err == nil && flatEvent.EventType != "" {
		// 重新设置请求体
		r.Body = io.NopCloser(bytes.NewBuffer(body))
		// 处理kubeeventer扁平格式事件
		h.handleKubeeventerFlatEvent(w, r, flatEvent)
		return
	}

	// 重新设置请求体
	r.Body = io.NopCloser(bytes.NewBuffer(body))

	// 尝试解析kubeeventer数组格式
	var kubeeventerEvent KubeeventerEvent
	if err := json.NewDecoder(r.Body).Decode(&kubeeventerEvent); err == nil && len(kubeeventerEvent.Events) > 0 {
		// 重新设置请求体
		r.Body = io.NopCloser(bytes.NewBuffer(body))
		// 处理kubeeventer格式的事件
		h.handleKubeeventerEvents(w, r, kubeeventerEvent)
		return
	}

	// 重新设置请求体
	r.Body = io.NopCloser(bytes.NewBuffer(body))

	// 如果不是kubeeventer格式，则尝试解析标准格式
	var alert agents.KubeEventAlert
	if err := json.NewDecoder(r.Body).Decode(&alert); err != nil {
		http.Error(w, fmt.Sprintf("解析事件数据失败: %v", err), http.StatusBadRequest)
		return
	}

	// 记录接收到事件的时间
	receivedTime := time.Now()
	fmt.Printf("[%s] 🔔 接收到Kubernetes事件: %s (Reason: %s, Namespace: %s)\n",
		receivedTime.Format("2006-01-02 15:04:05"),
		alert.Name,
		alert.Reason,
		alert.Namespace)

	// 添加数据源标识
	if alert.DataSource == "" {
		alert.DataSource = "kube-event"
	}

	// 处理事件
	agent, ok := h.agents["kube-event"]
	if !ok {
		http.Error(w, "Kubernetes事件 agent未注册", http.StatusInternalServerError)
		return
	}

	if err := agent.Process(alert); err != nil {
		http.Error(w, fmt.Sprintf("处理事件失败: %v", err), http.StatusInternalServerError)
		return
	}

	// 计算处理时间
	processingTime := time.Since(receivedTime)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	response := map[string]interface{}{
		"status":          "success",
		"message":         "Kubernetes事件处理成功",
		"source":          "kube-event",
		"event_name":      alert.Name,
		"event_reason":    alert.Reason,
		"event_namespace": alert.Namespace,
		"processing_time": fmt.Sprintf("%v", processingTime),
	}
	json.NewEncoder(w).Encode(response)
}

// handleKubeeventerFlatEvent 处理kubeeventer扁平格式事件
func (h *WebhookHandler) handleKubeeventerFlatEvent(w http.ResponseWriter, r *http.Request, flatEvent KubeeventerFlatEvent) {
	receivedTime := time.Now()

	fmt.Printf("[%s] 🔔 接收到kubeeventer扁平格式事件: %s (Kind: %s, Reason: %s)\n",
		receivedTime.Format("2006-01-02 15:04:05"),
		flatEvent.EventType,
		flatEvent.EventKind,
		flatEvent.EventReason)

	// 转换为标准格式并处理
	kubeEventProcessor, ok := h.agents["kube-event"].Processor.(*agents.KubeEventProcessor)
	if !ok {
		http.Error(w, "Kubernetes事件 processor类型错误", http.StatusInternalServerError)
		return
	}

	// 转换并处理事件 - 确保传递所有字段
	kubeeventerFlatEvent := agents.KubeeventerFlatEvent{
		EventType:      flatEvent.EventType,
		EventKind:      flatEvent.EventKind,
		EventReason:    flatEvent.EventReason,
		EventTime:      flatEvent.EventTime,
		EventMessage:   flatEvent.EventMessage,
		EventObject:    flatEvent.EventObject,
		EventNamespace: flatEvent.EventNamespace,
	}

	if err := kubeEventProcessor.ProcessKubeeventerFlatEvent(kubeeventerFlatEvent); err != nil {
		http.Error(w, fmt.Sprintf("处理事件失败: %v", err), http.StatusInternalServerError)
		return
	}

	// 计算处理时间
	processingTime := time.Since(receivedTime)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	response := map[string]interface{}{
		"status":          "success",
		"message":         "Kubernetes事件处理成功",
		"source":          "kube-event",
		"event_type":      flatEvent.EventType,
		"event_kind":      flatEvent.EventKind,
		"event_reason":    flatEvent.EventReason,
		"processing_time": fmt.Sprintf("%v", processingTime),
	}
	json.NewEncoder(w).Encode(response)
}

// handleKubeeventerEvents 处理kubeeventer格式的事件
func (h *WebhookHandler) handleKubeeventerEvents(w http.ResponseWriter, r *http.Request, kubeeventerEvent KubeeventerEvent) {
	receivedTime := time.Now()

	// 处理所有事件
	successCount := 0
	for _, event := range kubeeventerEvent.Events {
		fmt.Printf("[%s] 🔔 接收到kubeeventer Kubernetes事件: %s (Reason: %s, Namespace: %s)\n",
			receivedTime.Format("2006-01-02 15:04:05"),
			event.Name,
			event.Reason,
			event.Namespace)

		// 添加数据源标识
		if event.DataSource == "" {
			event.DataSource = "kube-event"
		}

		// 处理事件
		agent, ok := h.agents["kube-event"]
		if !ok {
			http.Error(w, "Kubernetes事件 agent未注册", http.StatusInternalServerError)
			return
		}

		if err := agent.Process(event); err != nil {
			fmt.Printf("❌ 处理事件失败: %v\n", err)
			continue
		}
		successCount++
	}

	// 计算处理时间
	processingTime := time.Since(receivedTime)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	response := map[string]interface{}{
		"status":          "success",
		"message":         fmt.Sprintf("成功处理 %d 个Kubernetes事件", successCount),
		"source":          "kube-event",
		"event_count":     len(kubeeventerEvent.Events),
		"success_count":   successCount,
		"processing_time": fmt.Sprintf("%v", processingTime),
	}
	json.NewEncoder(w).Encode(response)
}

// HandleFalcoAlert 处理Falco告警
func (h *WebhookHandler) HandleFalcoAlert(w http.ResponseWriter, r *http.Request) {
	// 检查端点是否启用
	if endpoint, ok := config.Global.Diting.Endpoints["falco"]; ok && !endpoint.Enabled {
		http.Error(w, "Falco端点已禁用", http.StatusForbidden)
		return
	}

	// 支持GET和POST方法，但GET方法只返回确认信息
	if r.Method != http.MethodPost && r.Method != http.MethodGet {
		http.Error(w, "只支持GET和POST方法", http.StatusMethodNotAllowed)
		return
	}

	// 如果是GET请求，返回确认信息
	if r.Method == http.MethodGet {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusOK)
		response := map[string]interface{}{
			"status":  "success",
			"message": "Falco webhook endpoint is ready",
			"method":  r.Method,
			"source":  "falco",
		}
		json.NewEncoder(w).Encode(response)
		return
	}

	var alert agents.FalcoAlert
	if err := json.NewDecoder(r.Body).Decode(&alert); err != nil {
		http.Error(w, fmt.Sprintf("解析告警数据失败: %v", err), http.StatusBadRequest)
		return
	}

	// 记录接收到告警的时间
	receivedTime := time.Now()
	fmt.Printf("[%s] 🔔 接收到Falco告警: %s (Rule: %s)\n",
		receivedTime.Format("2006-01-02 15:04:05"),
		alert.Output,
		alert.Rule)

	// 添加数据源标识
	if alert.DataSource == "" {
		alert.DataSource = "falco"
	}

	// 确保OutputFields存在
	if alert.OutputFields == nil {
		alert.OutputFields = make(map[string]interface{})
	}

	// 添加数据源标识到OutputFields
	alert.OutputFields["data_source"] = "falco"

	// 处理告警
	agent, ok := h.agents["falco"]
	if !ok {
		http.Error(w, "Falco agent未注册", http.StatusInternalServerError)
		return
	}

	if err := agent.Process(alert); err != nil {
		http.Error(w, fmt.Sprintf("处理告警失败: %v", err), http.StatusInternalServerError)
		return
	}

	// 计算处理时间
	processingTime := time.Since(receivedTime)

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	response := map[string]interface{}{
		"status":          "success",
		"message":         "Falco告警处理成功",
		"source":          "falco",
		"alert_rule":      alert.Rule,
		"alert_output":    alert.Output,
		"processing_time": fmt.Sprintf("%v", processingTime),
	}
	json.NewEncoder(w).Encode(response)
}

// HealthCheck 健康检查
func (h *WebhookHandler) HealthCheck(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{
		"status":  "ok",
		"message": "Webhook Agents服务运行正常",
		"agents":  "skywalking, kube-event, falco",
	})
}